package com.batchengine.worker;

import com.batchengine.pool.ProducerConsumerWorkerPool;
import com.batchengine.pool.WorkerPool;
import static com.batchengine.worker.Status.*;

import java.util.Date;
import java.util.TimerTask;

/**
 * Created by  solutions
 * Author: sunil.incubator@yahoo.com
 * Date: Jul 21, 2009
 */
public abstract class ScheduledTask extends TimerTask {

    private Long workId;

    protected String name;

    private Date scheduledTime = null;

    private Status status;

    protected WorkerPool workerPool;

    protected ScheduledTask() {
        setStatus(SCHEDULED);
    }

    protected ScheduledTask(Long jobId) {
        this.workId = jobId;
        setStatus(SCHEDULED);
    }

    protected ScheduledTask(Long jobId, String name) {
        this.name = name;
        this.workId = jobId;
        setStatus(SCHEDULED);
    }

    public Date getScheduledTime() {
        return scheduledTime;
    }

    public void setScheduledTime(Date scheduledTime) {
        this.scheduledTime = scheduledTime;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public WorkerPool getWorkerPool() {
        return workerPool;
    }

    public void setWorkerPool(WorkerPool workerPool) {
        this.workerPool = workerPool;
    }

    public Long getJobIdId() {
        return workId;
    }

    public void setWorkId(Long workId) {
        this.workId = workId;
    }

    /**
     * The method that does all the work. This is implemented by the
     * deriving class.
     *
     * @param
     * @throws InterruptedException throws InterruptedException
     */
    protected abstract void doWork(Long scheduledJobId) throws InterruptedException;

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public boolean cancel() {

//        if (super.cancel()) {
//            setStatus(CANCELED);
//            return true;
//        }
        setStatus(CANCELED);
        return true;
    }

    @Override
    public void run() {

        if(CANCELED.equals(getStatus())) {
            return;
        }
        try {
            setStatus(RUNNING);
            doWork(getJobIdId());
            startStopSignal();
        } catch (InterruptedException e) {
            System.out.println(this.getClass().getName());
            e.printStackTrace();
        }
    }

    public void startStopSignal() {

        if (null == workerPool) {
            return;
        }
        if (workerPool instanceof ProducerConsumerWorkerPool) {
            ProducerConsumerWorkerPool pool = (ProducerConsumerWorkerPool) workerPool;
            new PCStopSignal(String.format("StopSignal : %d", getJobIdId()), getJobIdId(), getWorkerPool(), pool.getDataGatherer()).run();
        } else {
            new ExecutorStopSignal(String.format("StopSignal : %d", getJobIdId()), getJobIdId(), getWorkerPool()).run();
        }
    }

    @Override
    public String toString() {
        return "ScheduledTask{" +
                "workId=" + workId +
                ", name='" + name + '\'' +
                ", scheduledTime=" + scheduledTime +
                ", status=" + status +
                ", workerPool=" + workerPool +
                '}';
    }
}